#include "mythreadforserial.h"
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
#include <QSharedMemory>
#include <QBuffer>
#include <QDataStream>
#include <QTimer>
#include <ctime>
#include "subwidget_serial.h"

#include <iostream>
#include <string>

extern bool g_isMysqlOpen;
extern int g_SaveFrame;

MyThreadForSerial::MyThreadForSerial()
{
    //SharedMemory_write();
    m_Serial = new SubWidget_Serial;
}

void MyThreadForSerial::show()
{
    m_Serial->show();
}

void MyThreadForSerial::run()
{
//    Serial_init();
    SharedMemory_read();
    SharedMemory_read();
    SharedMemory_read();
    msleep(2000);
    SharedMemory_read();
    SharedMemory_read();
    SharedMemory_read();
    int i=0, j=0;
    //测试用--模拟发送数据
    while (1)
    {
        msleep(1000);
        //srand((unsigned int)time(NULL));
        int data = rand()%100;      //将随技术范围映射到0-100
        emit(m_Serial->get_data(1,(double)data));
        i++;
        if(i>g_SaveFrame && g_isMysqlOpen)
        {
            emit(m_Serial->push_to_sql(1, data));
            i = 0;
        }
//        std::cout<<"12342134";      //貌似最后一起被打印出来
        SharedMemory_read();
        //SharedMemory_readNative();
    }
}

double MyThreadForSerial::receive_message(QByteArray d)
{
    //目前应答帧有7字节
    const int data_frame_len = 7;
    char* dp = d.data();
    int bufferSize = d.size();          //返回里面有几个字节的数据，一个字节有8位，正好一个字节就是一个char，同时char是最小的存储单位，所以用char来存数据
    int index = 0;
    m_datafrm.clear();
    while (index < bufferSize)
    {
        m_datafrm.append(dp[index]);
        index++;
        if(m_datafrm.size() == data_frame_len)
        {
            m_datafrm.print();
            //  TODO 写deal程序
            double data_value = deal_humidity(m_datafrm);
            m_datafrm.clear();
            return data_value;
        }
    }
    qDebug()<<"SubWidget_Serial::receive_message未收到数据";
    return 0;
}

MyThreadForSerial::DataFrame::DataFrame()
{

}

void MyThreadForSerial::DataFrame::append(char d)
{
    datas.push_back(d);
}

void MyThreadForSerial::DataFrame::clear()
{
    datas.clear();
    datas.resize(16);
}

char& MyThreadForSerial::DataFrame::operator[](std::size_t index)
{
    return datas[index];
}

const char& MyThreadForSerial::DataFrame::operator[](std::size_t index) const
{
    return datas[index];
}

void MyThreadForSerial::DataFrame::print()
{
    for(char c: datas)
    {
        fprintf(stdout, "%02X", c);
    }
    fprintf(stdout, "/n");
    fflush(stdout);
}

std::size_t MyThreadForSerial::DataFrame::size()
{
    return datas.size();
}

double MyThreadForSerial::deal_humidity(DataFrame datafrm)
{
    double humidty;
    humidty = ((double)(unsigned char)(datafrm[3]<<2)+(double)(unsigned char)datafrm[4])/10;         //让高位左移两位
    qDebug()<<"水分： "<<humidty;
    return humidty;
}

const SubWidget_Serial& MyThreadForSerial::get() const
{
    return *m_Serial;
}

void MyThreadForSerial::SharedMemory_write()
{
    //创建共享内存对象
    //m_SharedMemory = new QSharedMemory("SharedMermoryForSerial");
    m_SharedMemory_write = new QSharedMemory();
    //创建内存共享
    m_SharedMemory_write->setKey("SharedMermoryForSerial");   //声明共享内存的密秘钥
    //将共享内存与当前线程绑定
    if(m_SharedMemory_write->isAttached())           //感觉这里应该是尝试关联一个新的内存块，如果是已经存在的内存，则就使用attach()
    {
        //将线程与共享内存块分离
        if(!m_SharedMemory_write->detach())
        {
             qDebug() << "Unable to detach from shared memory.";
        }
    }
    bool ok;
    QString text = "hello world!";

    if(text.length())       //判断是否有内容
    {
        QBuffer buffer;                     //将字符串转为字节的介质
        buffer.open(QBuffer::ReadWrite);
        QDataStream out(&buffer);           //数据流
        out << text;
        int size = buffer.size();           //获得字节大小
        //创建共享内存
        if(!m_SharedMemory_write->create(size))
        {
            qDebug() << m_SharedMemory_write->errorString() << "\n Unable to create shared memory segment.";
            //return ;
            m_SharedMemory_write->attach();     //如果无法创建以当前key为标识的共享内存，则说明内存已被创建(或者说还在使用，还没有被销毁)，则我们通过attach()进行联系
        }
        //向共享内存写数据
        m_SharedMemory_write->lock();         //锁定共享内存
        char *to = (char*)m_SharedMemory_write->data(); //将指向刚创建内存的地址传给指针变量to
        const char *from = buffer.data().data(); //被共享内存的数据
        memcpy(to , from, qMin(m_SharedMemory_write->size(), size));
        m_SharedMemory_write->unlock();
    }
}

void MyThreadForSerial::SharedMemory_read()
{
    //创建共享内存对象
    m_SharedMemory_read = new QSharedMemory();
    //m_SharedMemory_read->setKey("SharedMermoryForSerial"); //声明共享内存的秘钥
    m_SharedMemory_read->setNativeKey("SharedMermoryForSerial");
    //将当前进程与共享内存绑定
    if(!m_SharedMemory_read->attach())
    {
        qDebug()<<"读数据时，内存绑定失败";
        return;
    }

    // 从共享内存中读数据
    QBuffer buffer; //声明缓冲区
    QDataStream in(&buffer); //声明数据流
    QString text;
    char text_test[97];
    m_SharedMemory_read->lock();
    //用缓冲区得到共享内存关联后得到的数据和数据大小
    buffer.setData((char*)m_SharedMemory_read->constData(), m_SharedMemory_read->size());
    buffer.open(QBuffer::ReadOnly);     //设置读模式
    in >> text;//使用数据流从缓冲区获得共享内存的数据，然后输出到字符串中
    qDebug()<<"1 "<<in;
    m_SharedMemory_read->unlock();
    m_SharedMemory_read->detach();      //与共享内存空间分离
    qDebug()<<text;
}

void MyThreadForSerial::SharedMemory_readNative()
{
    //创建共享内存对象
    m_SharedMemory_read = new QSharedMemory();
    //m_SharedMemory_read->setKey("SharedMermoryForSerial"); //声明共享内存的秘钥
    m_SharedMemory_read->setNativeKey("SharedMermoryForSerial");
    //将当前进程与共享内存绑定
    if(!m_SharedMemory_read->attach(QSharedMemory::ReadOnly))
    {
        qDebug()<<"读数据时，内存绑定失败";
        return;
    }
    qDebug()<<"1 3  ";
    // 从共享内存中读数据
    //3 读取数据
   char peopleInfo[97];
   qDebug()<<"1 2  "<<QString(peopleInfo);
   m_SharedMemory_read->lock();//加锁
   memcpy(&peopleInfo, (char*)m_SharedMemory_read->constData(), m_SharedMemory_read->size());
   m_SharedMemory_read->unlock();//解锁
   qDebug()<<"2   "<<QString(peopleInfo);
}












